`timescale	1ps/1ps
module phy_interface(
		//时钟和复位
                input	wire		resetb,
                input   wire		sclk,
                input   wire		clk_25M,

                input	wire		sub_mode,
                input	wire	[7:0]	local_depth,
                input	wire		cas_depth_adj,

		//其他外部相关信号
		input	wire		tx_err_en,
		input	wire		time_1ms,
		input	wire		time_125ms,
		
		//PORTA接口
		input	wire		gp0_rxc,
		input	wire		gp0_rxdv,
		input	wire	[3:0]	gp0_rxd,
		output	wire		gp0_txc,
		output	wire		gp0_txen,
		output	wire	[3:0]	gp0_txd,
		
		//PORTB接口
		input	wire		gp1_rxc,
		input	wire		gp1_rxdv,
		input	wire	[3:0]	gp1_rxd,
		output	wire		gp1_txc,
		output	wire		gp1_txen,
		output	wire	[3:0]	gp1_txd,
		
		//PORTA转发接收
		output	wire		rx_clk,
		output	wire		rx_dv,
		output	wire	[7:0]	rx_data,
		output	wire	[1:0]	rx_type,
		
		//PORTB转发发送
		input	wire	[1:0]	tx_ck,
		input	wire		tx_en,
		input	wire	[7:0]	tx_data,
		
		//给内部的接收接口
		output	wire		rec_flag_a,
		output	wire		rec_flag,
		output	wire	[7:0]	rec_data,
		output	wire		rec_error,
		output	wire		rec_error_sync,
		
		//内部的发送接口
		input 	wire 	[1:0]	force_send,
		input	wire		send_flag,
		input	wire		pre_flag,
		input	wire	[7:0]	send_data,
		
		//给内部的其他信号
		output	wire		input_port,
		output	wire	[1:0]	rec_vendor,
		output	wire		yt_vs_pre,
		output	wire		input_active,
		output	wire		redu_flag,
		output	wire		blank_flag,
		output	wire	[7:0]	phy_state,
		
		//调试用信号输出
		output	wire	[15:0]	tout
		);

//**************************************************************
//		   参数定义
//**************************************************************    

//**************************************************************
//		   信号定义
//**************************************************************    
wire		gp0_rx_clk,gp0_rx_dv,gp1_rx_clk,gp1_rx_dv;
wire	[7:0]	gp0_rx_data,gp1_rx_data;
wire	[1:0]	gp0_rx_type,gp1_rx_type;
wire		gp0_tx_en,gp1_tx_en;
wire	[7:0]	gp0_tx_data,gp1_tx_data;

wire		gp0_rec_flag,gp0_rec_error,gp0_blank_flag,gp1_rec_flag,gp1_rec_error,gp1_blank_flag;
wire	[7:0]	gp0_rec_data,gp1_rec_data;
wire		send_sync_gp0, send_sync_gp1, send_flag_gp0, pre_flag_gp0, send_flag_gp1, pre_flag_gp1;
wire	[7:0]	send_data_gp0, send_data_gp1;

wire	[1:0]	gp0_tx_ck,gp1_tx_ck;
wire	[3:0]	port_state;

//**************************************************************
//		   转发接口
//**************************************************************   
assign	rx_clk = gp0_rx_clk;
assign	rx_dv = gp0_rx_dv;
assign	rx_data = gp0_rx_data;
assign	rx_type = gp0_rx_type;

//**************************************************************
//		   接口逻辑
//**************************************************************    
//PORTA接收接口
phy_RGMII_rec_io rec_io_a(
		.rst(~resetb),

		.rxc(gp0_rxc),
		.rxdv(gp0_rxdv),
		.rxd(gp0_rxd),		
			
		.rx_clk(gp0_rx_clk),
		.rx_dv(gp0_rx_dv),
		.rx_data(gp0_rx_data),

		.rx_er(),
		.rx_crs(),
		.rx_col()
		);
		
//检测PORTA接收时钟频率
phy_rx_clk_check	rx_clk_check_p0(
	.sclk(sclk),
	.rx_clk(gp0_rx_clk),	
	.clk_type(gp0_rx_type),
	.mega_clk_sel()
	);

//PORTA发送接口
phy_RGMII_trans_io trans_io_a(
		.rst(~resetb),

		.tx_clk(sclk),
		.tx_en(gp0_tx_en),
		.tx_data(gp0_tx_data),

		.tclk(sclk),
		.tx_ck(gp0_tx_ck),

		.txc(gp0_txc),
		.txen(gp0_txen),
		.txd(gp0_txd)		
		);

//PORTB接收接口
phy_RGMII_rec_io rec_io_b(
		.rst(~resetb),

		.rxc(gp1_rxc),
		.rxdv(gp1_rxdv),
		.rxd(gp1_rxd),		
			
		.rx_clk(gp1_rx_clk),
		.rx_dv(gp1_rx_dv),
		.rx_data(gp1_rx_data),

		.rx_er(),
		.rx_crs(),
		.rx_col()
		);

//检测PORTB接收时钟频率
phy_rx_clk_check	rx_clk_check_p1(
	.sclk(sclk),
	.rx_clk(gp1_rx_clk),	
	.clk_type(gp1_rx_type),
	.mega_clk_sel()
	);

//PORTB发送接口
assign	gp1_tx_ck = tx_ck;
assign	gp1_tx_en = tx_en;
assign	gp1_tx_data = tx_data;
 
phy_RGMII_trans_io trans_io_b(
		.rst(~resetb),

		.tx_clk(sclk),
		.tx_en(gp1_tx_en),
		.tx_data(gp1_tx_data),

		.tclk(sclk),
		.tx_ck(gp1_tx_ck),

		.txc(gp1_txc),
		.txen(gp1_txen),
		.txd(gp1_txd)
		);

reg	[3:0]	div_100M_count;
reg		sync_100M;

always@(posedge	sclk or negedge resetb)
	if(resetb==0)
		div_100M_count <= 0;
	else if (div_100M_count >= 9)
		div_100M_count <= 0;
	else
		div_100M_count <= div_100M_count + 1;

always@(posedge	sclk)
	if (div_100M_count == 8)
		sync_100M <= 1;
	else
		sync_100M <= 0;

//PORTA控制模块
phy_cascade_ctrl_01 cascade_ctrl_a(
		.resetb(resetb),
		.sclk(sclk),
		.sync_100M(sync_100M),

		.sub_mode(sub_mode),
		.cas_depth_adj(cas_depth_adj),
		.local_depth(local_depth),

		.rx_clk(gp0_rx_clk),
		.rx_dv(gp0_rx_dv),
		.rgmii_rx_data(gp0_rx_data),
		.rx_type(gp0_rx_type),
		.tx_type(gp1_rx_type),
		
		.rec_flag(gp0_rec_flag),
		.rec_data(gp0_rec_data),
		.rec_error(gp0_rec_error),

		.send_sync(send_sync_gp1),
		.force_send(force_send[1]),
		.ack_port(input_port),
		.i_tx_en(send_flag_gp1),
		.i_tx_pre(pre_flag_gp1),
		.i_tx_data(send_data_gp1),
		
		.blank_flag(gp0_blank_flag),

		.tx_ck(),
		.tx_en(),
		.tx_data(),

		.tx_err_en(tx_err_en),

		.tout()
		);

//PORTB控制模块
phy_cascade_ctrl_01 cascade_ctrl_b(
		.resetb(resetb),
		.sclk(sclk),
		.sync_100M(sync_100M),

		.sub_mode(sub_mode),
		.cas_depth_adj(cas_depth_adj),
		.local_depth(local_depth),

		.rx_clk(gp1_rx_clk),
		.rx_dv(gp1_rx_dv),
		.rgmii_rx_data(gp1_rx_data),
		.rx_type(gp1_rx_type),
		.tx_type(gp0_rx_type),//2
		
		.rec_flag(gp1_rec_flag),
		.rec_data(gp1_rec_data),
		.rec_error(gp1_rec_error),

		.send_sync(send_sync_gp0),
		.force_send(force_send[0]),
		.ack_port(~input_port),
		.i_tx_en(send_flag_gp0),
		.i_tx_pre(pre_flag_gp0),
		.i_tx_data(send_data_gp0),
		
		.blank_flag(gp1_blank_flag),
		
		.tx_ck(gp0_tx_ck),
		.tx_en(gp0_tx_en),
		.tx_data(gp0_tx_data),

                .tx_err_en(tx_err_en),

		.tout()
		);

//端口级联方向选择
phy_port_select_01 port_select(
		.resetb(resetb),
		.sclk(sclk),
		
		.flash_ms(time_1ms),
                .time_125ms(time_125ms),
                
		.gp0_rec_flag(gp0_rec_flag),
		.gp0_rec_data(gp0_rec_data),
		.gp0_rec_error(gp0_rec_error),
		.gp0_blank_flag(gp0_blank_flag),
		
		.gp1_rec_flag(gp1_rec_flag),
		.gp1_rec_data(gp1_rec_data),
		.gp1_rec_error(gp1_rec_error),
		.gp1_blank_flag(gp1_blank_flag),
		
		.rec_flag_a(rec_flag_a),
		.rec_flag(rec_flag),
		.rec_data(rec_data),
		.rec_error(rec_error),
		.rec_vendor(rec_vendor),
		.rec_error_sync(rec_error_sync),
		.yt_vs_pre(yt_vs_pre),
		
		.blank_flag(blank_flag),
		.redu_flag(redu_flag),
		
                .input_port(input_port),
		.input_active(input_active),
		.port_state(port_state),
		
		.tout()
		);

phy_tx_convert_01 tx_convert_gp0(
		.resetb(resetb),
		.sclk(sclk),	//125M
		
		.send_flag_i(send_flag),
		.pre_flag_i(pre_flag),
		.send_data_i(send_data),
			
		.send_sync(send_sync_gp0),
		.send_flag(send_flag_gp0),
		.pre_flag(pre_flag_gp0),
		.send_data(send_data_gp0),
		
		.tout()
		);

phy_tx_convert_01 tx_convert_gp1(
		.resetb(resetb),
		.sclk(sclk),	//125M
		
		.send_flag_i(send_flag),
		.pre_flag_i(pre_flag),
		.send_data_i(send_data),
			
		.send_sync(send_sync_gp1),
		.send_flag(send_flag_gp1),
		.pre_flag(pre_flag_gp1),
		.send_data(send_data_gp1),
		
		.tout()
		);

assign	phy_state = {port_state,gp1_rx_type,gp0_rx_type};

//************************************************************
//			测试信号
//************************************************************
assign	tout = {gp1_rx_dv, gp1_tx_en, gp0_rx_dv, gp0_tx_en};

endmodule


